<?php

/**
 * 计数器类
 * @copyright Copyright&copy; 2015, 广州六象元一网络科技有限公司
 * @author 王海龙 $
 * @version  $Id: classCounter.php, v 1.0, 2015-01-01 王海龙 $
 * 基本操作：
 * $mem            memcached实例化
 * add      添加计数器
 * in       增计数器的值
 * de       减计数器的值
 * monitor  监听计数器的值
 * get      获取计数器的值
 */

class classCounter {
    public $mem; // memcached
    private $maxCount = 100; // 错误最大循环次数
    private $usleep = 10000; // 循环回调执行间隔/微秒
    private $config = array('512145b6f8ea49a5.m.cnqdalicm9pub001.ocs.aliyuncs.com', 11211, '512145b6f8ea49a5', 'Eggms520');

    /**
     * 构造函数
     *
     * @param   array   配置数组 : $config = array('host'=>'','user'=>'','pass'=>'','port'=>'');
     */
    public function __construct($config = array()) {
        if (empty($config)) {
            $config = $this->config;
        } else {
            return false;
        }
        $this->connect($config);
    }

    /**
     * memcached连接
     *
     * @access  private
     * @param   array   配置数组
     * @return  boolean
     */
    private function connect($config = array()) {
        $this->mem = M('counter');
    }

    /**
     * 添加计数器
     * @access  public
     * @param   $name  string  计数器名称
     * @param   $value int     计数器初始值
     * @param   $timeOut int   计数器有效时间/秒
     * @return  bool  返回是否成功
     */
    public function add($name = false, $value = 0, $timeOut = false){
        if (!empty($name)) {
            $count = 0;
            while ($count < $this->maxCount){
                if ($this->mem->add($name, $value, $timeOut)) {
                    return true;
                    break;
                } else {
                    $int = $this->mem->get($name);
                    if (!empty($int) || $int == '0') {
                        return true;
                        break;
                    } else {
                        usleep($this->usleep);
                        $count ++;
                    }
                }
            }
        }
        return false;
    }

    /**
     * 计数器计数
     * @access  public
     * @param   $name  string  计数器名称
     * @param   $value int     计数器计数值
     * @return  int  返回计数器的值或失败
     */
    public function in($name = false, $value = 1, $count = 0) {
        if (!empty($name) && !empty($value)) {
            $count = 0;
            while ($count < $this->maxCount){
                $int = $this->mem->increment($name, $value);
                if (!empty($int) || $int == '0') {
                    return $int;
                    break;
                } else {
                    usleep($this->usleep);
                    $count ++;
                }
            }
        }
        return false;
    }
    /**
     * 计数器计数
     * @access  public
     * @param   $name  string  计数器名称
     * @param   $value int     计数器计数值
     * @return  int  返回计数器的值或失败
     */
    public function de($name = false, $value = 1, $count = 0) {
        if (!empty($name) && !empty($value)) {
            $count = 0;
            while ($count < $this->maxCount){
                $int = $this->mem->decrement($name, $value);
                if (!empty($int) || $int == '0') {
                    return $int;
                    break;
                } else {
                    usleep($this->usleep);
                    $count ++;
                }
            }
        }
        return false;
    }

    /**
     * 计数器监听
     * @access  public
     * @param   $name  string  计数器名称
     * @param   $value int     需要监听的数字
     * @param   $usleep int    监听间隔（微秒）
     * @param   $maxCount int  监听最大次数
     * @param   $count int     当前监听次数
     * @return  bool  返回监听成攻或失败
     */
    public function monitor($name = false, $value = false, $usleep = 10000, $maxCount = 1000) {
        if (!empty($name) && intval($value)) {
            $usleep = !empty($usleep) ? intval($usleep) : $this->usleep; // 监听间隔
            $maxCount = !empty($maxCount) ? intval($maxCount) : $this->maxCount; // 监听最大次数
            $count = 0;
            while ($count < $maxCount){
                $int = $this->mem->get($name);
                if ($int == $value) {
                    return true;
                    break;
                } else {
                    usleep($usleep);
                    $count ++;
                }
            }
        }
        return false;
    }

    /**
     * 获取计数器的值
     * @access  public
     * @param   $name  string  计数器名称
     * @return  int  返回计数器的值
     */
    public function get($name = false) {
        if (!empty($name)) {
            $count = 0;
            // 取号，将计数器加1
            while ($count < $this->maxCount){
                $int = $this->mem->get($name);
                if (!empty($int) || $int == '0') {
                    return $int;
                    break;
                } else {
                    $count ++;
                }
            }
        }
        return false;
    }
}
